from libs import json_response
from utils.viewset import CustomModelViewSet
from rest_framework.views import APIView
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from threading import Thread
from django_redis import get_redis_connection
from application import settings
from main.script.models import Script, ScriptRecord, GameVersion
from main.script.serializers import ScriptSerializer, ScriptCreateUpdateSerializer, ScriptDetailSerializer
from utils.tools import human_datetime, AttrDict
from libs.parser import Argument, JsonParser, AttrDict
from main.script.utils import deploy_dispatch
import uuid
import re


class ScriptViewSet(CustomModelViewSet):
    queryset = Script.objects.all()
    serializer_class = ScriptSerializer
    create_serializer_class = ScriptCreateUpdateSerializer
    update_serializer_class = ScriptCreateUpdateSerializer


class ScriptDetailViewSet(CustomModelViewSet):
    queryset = ScriptRecord.objects.all()
    serializer_class = ScriptDetailSerializer


class ScriptExecView(APIView):
    def get(self, request):
        """获取指定id的脚本执行日志"""
        params, error = JsonParser(
            Argument('id'),
            Argument('rid', required=False),
        ).parse(request.GET)
        outputs = list()
        r_id = f'{params.id}:{params.rid}'
        rds, key, counter = get_redis_connection(), f'{settings.REQUEST_KEY}:{r_id}', 0
        data = rds.lrange(key, counter, counter + 9)
        while data:
            counter += 10
            outputs.extend(x.decode() for x in data)
            data = rds.lrange(key, counter, counter + 9)
        return json_response(data=outputs)

    def post(self, request):
        """获取参数执行脚本"""
        params, error = JsonParser(
            Argument('id'),
            Argument('env', type=dict)
        ).parse(request.data)
        task = AttrDict()
        script = Script.objects.filter(id=params.id).first()
        if re.match(r'(.*)测试服更新', script.group.name) is not None:
            task.extend = script.project
        token = uuid.uuid4().hex
        task.build_id = token
        task.state = 2
        task.build_at = human_datetime()
        task.build_by = request.user.username
        task.task_id = params.id
        task.token = token
        ScriptRecord.objects.create(**task)
        task = ScriptRecord.objects.filter(build_id=task.build_id, task_id=task.task_id).first()
        Thread(target=deploy_dispatch, args=(params.env, task, token, script)).start()
        return json_response(data={'token': token, 'build_id': task.build_id})


@api_view(['GET'])
@permission_classes((IsAuthenticated,))
def get_project_language_list(request):
    scripts = Script.objects.all()
    project_list = [v['project'] for v in scripts.order_by('project').values('project').distinct() if
                    v['project']]
    language_list = [v['language'] for v in scripts.order_by('language').values('language').distinct() if
                     v['language']]
    return json_response(data={
        'projectList': project_list,
        'languageList': language_list,
    })


@api_view(['GET'])
@permission_classes((IsAuthenticated,))
def get_game_version(request):
    params, error = JsonParser(
        Argument('project'),
        Argument('language'),
    ).parse(request.GET)
    if error:
        return json_response(error=error)
    versions = GameVersion.objects.filter(game_type=params.project, language=params.language).order_by(
        '-create_datetime')[:5]
    version_list = []
    for ver in versions:
        version_list.append(ver.version + ver.suffix)
    return json_response(data=version_list)
